import 'dart:async';
import 'dart:io';

import 'package:audio_service/audio_service.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:hc_cure_sdk_flutter/common/exception/auth.dart';
import 'package:hc_cure_sdk_flutter/common/extension/play_state.ex.dart';
import 'package:hc_cure_sdk_flutter/common/player/player.dart';
import '../common/model/channel.dart';
import '../common/model/player_record.dart';
import '../common/routes.dart';
import '../common/service/channel/channel.dart';
import '../common/service/sdk_service.dart';
import 'state/state.dart';

class PlayerController extends FullLifeCycleController with FullLifeCycleMixin {
  final CurePlayerState state;

  Channel? get channel => Get.find<ChannelService>().channel;

  final IASMRPlayer player = IASMRPlayer.player();

  StreamSubscription<Duration>? _positionSub;

  StreamSubscription<PlaybackState>? _stateSub;

  PlayerController(this.state);

  final playButtonNode = FocusNode();

  final record = PlayerRecord();

  _initData() async {
    listenPlayerStatus();
    await prepareAudio();
    notifyUpdateUI();
  }

  void goBack() async {
    _positionSub?.cancel();

    record.update(state.timePosition);

    Get.back();
  }
  // @override
  // void onInit() {
  //   super.onInit();
  // }

  @override
  void onReady() {
    super.onReady();
    playButtonNode.requestFocus();
    _initData();
  }

  @override
  void onClose() {
    stop();
    _positionSub?.cancel();
    _stateSub?.cancel();
    playButtonNode.dispose();
    super.onClose();
  }

  /* app life* */
  @override
  void onDetached() {}

  @override
  void onHidden() {
    debugPrint("onHidden");
    exit(1);
  }

  @override
  void onInactive() {
    debugPrint("onInactive");
  }

  @override
  void onPaused() {
    debugPrint("onPaused");
  }

  @override
  void onResumed() {
    if (state.isOver) {
      Get.offAllNamed(Routes.kChat);
    }
  }
}

extension PlayerEX on PlayerController {
  bool get isPlaying => player.isPlaying;

  String get buttonTitle => isPlaying ? "暂停" : "播放";

  void pause() {
    player.pause();
  }

  void play() {
    player.play();
  }

  Future stop() async {
    await player.dispose();
  }
}

extension on PlayerController {
  void notifyUpdateUI() {
    update(["player"]);
  }
}

extension on PlayerController {
  bool get isActive =>
      AppLifecycleState.resumed == WidgetsBinding.instance.lifecycleState;

  Future prepareAudio() async {
    try {
      await EasyLoading.show();
      final sdk = Get.find<SDKService>();
      final solution = await sdk.fetchCureSolution(
        cure: state.cure,
        duration: state.duration,
      );

      state.lastSolution = solution;

      await player.prepare(
        solution: solution,
        duration: state.duration,
        id: state.cure.id.toString(),
        title: state.cure.name,
      );
      await Future.delayed(1.seconds);
      record.start(state.cure);
      await player.play();
      await EasyLoading.dismiss();
    } on PlatformException catch (e) {
      EasyLoading.showError(e.toString());
      if (e.isAuthExpired) {
        return;
      }
    } catch (e) {
      debugPrint(e.toString());
      EasyLoading.showError(e.toString());
    } finally {
      state.isMusicStandby = true;
      notifyUpdateUI();
    }
  }

  void listenPlayerStatus() {
    _positionSub = AudioService.position.asBroadcastStream().listen((value) {
      state.timePosition = value;
      record.update(value);

      if (isActive) {
        notifyUpdateUI();
      }
    });

    _stateSub = player.playbackState.asBroadcastStream().listen((e) {
      state.isOver = e.isOver && state.hasSolution;
      if (state.isOver && isActive) {
        goBack();
      }
      if (isActive) {
        notifyUpdateUI();
      }
    });
  }
}
